package yzbx.personalwebsite.tool;

import com.alibaba.fastjson2.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import yzbx.personalwebsite.config.ConfigData;

import java.util.ArrayList;
import java.util.List;

/**
 * {@code @Author} zxm
 * {@code @Description} 用于连接redis
 * {@code @Date} 2024/09/27/17:53
 * {@code @Version} 1.0
 */
@Component
public class RedisTool {

    private static final Logger LOGGER = LoggerFactory.getLogger(RedisTool.class);

    // redis过期时间 5分钟
    public static final int REDIS_SAVE_TIME_5M = 5 * 60;

    // redis过期时间 4小时
    public static final int REDIS_SAVE_TIME_4H = 4 * 60 * 60;

    private final ConfigData configData;

    @Autowired
    public RedisTool(ConfigData configData) {
        this.configData = configData;
    }

    /**
     * 获取Redis实例
     *
     * @return redis
     */
    public Jedis redisConnect() {
        //连接redis的信息，所有关于redis操作的功能都在Jedis类中
        Jedis jedis = new Jedis(configData.getRedisIp(), configData.getRedisPort());
        jedis.connect();
        return jedis;
    }

    public void redisClose(Jedis jedis) {
        jedis.close();
    }


    /**
     * 判断redis连通性
     *
     * @return 是否连通
     */
    public boolean pingRedis() {
        // 创建Jedis实例来尝试连接Redis服务器
        try (Jedis jedis = new Jedis(configData.getRedisIp(), configData.getRedisPort())) {
            String response = jedis.ping();
            if ("PONG".equals(response)) {
                return true;
            } else {
                LOGGER.info("连接Redis服务器失败");
                return false;
            }
        } catch (Exception e) {
            LOGGER.warn("连接Redis服务器失败: {}", e.getMessage());
        }
        return false;
    }

    public <T> List<T> getValue(String logTheme, String key) {
        LOGGER.info("开始获取{}数据", logTheme);
        if (!key.isEmpty() && pingRedis()) {
            try (Jedis jedis = redisConnect()) {
                if (jedis.exists(key)) {
                    int ttl = (int) jedis.ttl(key);
                    int hour = ttl / 3600;
                    int min = (ttl % 3600) / 60;
                    int sec = ttl % 60;
                    LOGGER.info("缓存中有已有{}数据({}小时{}分{}秒后过期)", logTheme, hour, min, sec);
                    return JSON.parseObject(jedis.get(key), List.class);
                }
            }
        }
        LOGGER.info("{}数据不存在缓存中", logTheme);
        return new ArrayList<>();
    }

    public <T> void setValue(String logTheme, String key, List<T> list, int saveTime) {
        if (pingRedis()) {
            if (list != null && !list.isEmpty()) {
                try (Jedis jedis = redisConnect()) {
                    jedis.setex(key, saveTime, JSON.toJSONString(list));
                    LOGGER.info("{}数据{}添加到缓存中", logTheme, key);
                }
            }
        }
    }

    public void delValue(String logTheme, String key) {
        if (pingRedis()) {
            try (Jedis jedis = redisConnect()) {
                if (jedis.exists(key)) {
                    jedis.del(key);
                    LOGGER.info("{}数据已从缓存中删除", logTheme);
                }
            }
        }
    }

    public void addSaveTime(String logTheme, String key, int saveTime) {
        if (pingRedis()) {
            try (Jedis jedis = redisConnect()) {
                if (jedis.exists(key)) {
                    jedis.expire(key, saveTime);
                    LOGGER.info("{}数据已延长缓存时间", logTheme);
                }
            }
        }
    }

//    private void test() {
//        Jedis jedis = redisConnect();
//        //关于key的命令
//        //获取所有key值
//        Set<String> keys = jedis.keys("*");
//        System.out.println("获取所有的keys：" + keys);
//        //删除key的个数
//        long del = jedis.del("ll", "l1");
//        System.out.println("删除key的个数" + del);
//        //判定指定的key是否存在
//        boolean k4 = jedis.exists("k4");
//        System.out.println("判断指定的k4是否存在" + k4);
//        //给key指定过期时间
//        jedis.expire("lll", 100);
//
//
//        //string类型
//        //添加数据
//        String set = jedis.set("k1", "v1");
//        System.out.println("存入k1的值" + set);
//        //获取指定的值
//        String s = jedis.get("k1");
//        System.out.println("获取指定k1的值" + s);
//        //判断指定的值是否存在，若不存在，就创建
//        long k2 = jedis.setnx("k2", "v2");
//        System.out.println("如果k2不存在，则设置k2的值：" + k2);
//        jedis.setnx("k3", "110");
//        //值递增
//        long k3 = jedis.incr("k3");
//        System.out.println("k3的值加1" + k3);
//        //值递减
//        long k31 = jedis.decr("k3");
//        System.out.println("k3的值减1" + k31);
//        //创建key并指定过期时间
//        String setex = jedis.setex("k4", 100, "v3");
//        System.out.println(setex);
//        //关于hash的命令
//        //存值
//        long hset = jedis.hset("h1", "name", "lay");
//        System.out.println("存入h1的键值对：" + hset);
//        //设置一个map
//        Map<String, String> map = new HashMap<>();
//        map.put("name", "章三");
//        map.put("age", "18");
//        long h2 = jedis.hset("h2", map);
//        System.out.println("存入h2的键值对" + h2);
//        //取值
//        String hget = jedis.hget("h2", "name");
//        System.out.println("获取h2中name的值" + hget);
//        //获取key中的素有键值对的值
//        Map<String, String> h21 = jedis.hgetAll("h2");
//        System.out.println("获取h2中所有键值对的值" + h21);
//        //获取所有哈希表中的值
//        List<String> h22 = jedis.hvals("h2");
//        System.out.println(h22);
//        //获取所有哈希表中所有的字段
//        Set<String> h23 = jedis.hkeys("h2");
//        System.out.println(h23);
//
//        //(1).键的操作
////        jedis.flushDB();//清空数据
////        jedis.set("key1","value1");//设置数据
////        jedis.exists("key1");//判断键是否存在
////        Set<String> keys= jedis.keys("*");//获取所有键
////        jedis.del("key1");//删除键
////        jedis.expire("key1",10);//设置键过期/秒
////        jedis.ttl("key1");//获取键的剩余生存时间
////        jedis.type("key1");//查看键对应值的数据类型
//
//        //(2).字符串的操作
//        jedis.set("key", "value");//增加或覆盖数据项
//        jedis.setnx("key", "value");//非覆盖增加
//        jedis.setex("key", 3, "value");//增加数据项并设置过期时间
//        jedis.get("key");//获取key的数据项
//        jedis.append("key", "1");//在key的value后面追加1，如果key不存在就创建
//        jedis.mset("key1", "value1", "key2", "value2");//增加多个键值对
//        List<String> strs = jedis.mget("key1", "key2");//获取多个key对应value
//        jedis.del(new String[]{"key1", "key2"});//删除多个key
//        jedis.getSet("key", "123");//获取value并更新value
//
//
//        //(3).整数和浮点数操作
//        jedis.set("key", "1");//value为可转化的数字
//        jedis.incr("key");//value加1
//        jedis.incrBy("key", 2);//value加n
//        jedis.decr("key");//value减1
//        jedis.decrBy("key", 2);//value减n
//
//        //(4).List操作
//        jedis.lpush("key", "1", "2", "3");//添加一个list
//        jedis.rpush("key", "1", "2", "3");//添加一个list
//        jedis.lpop("key");//对应list左出栈一个元素
//        jedis.rpop("key");//对应list右出栈一个元素
//        jedis.llen("key");//获取key对应list长度
//        jedis.lset("key", 1, "f");//修改key对应list下标n对应的元素
//        jedis.lindex("key", 1);//获取key对应list下标n对应元素
//        jedis.sort("key");//key对应list的元素从小到大排序
//
//        //(5).set操作
//        jedis.sadd("key", "1", "2", "3", "4");//添加一个set
//        jedis.sadd("key1", "12", "2", "33", "4");//添加一个set
//        Set<String> strings = jedis.smembers("key");//获取set对应元素
//        jedis.srem("key", "1");//删除set下值为1的元素
//        jedis.spop("key");//随机出栈set里的某个元素
//        jedis.scard("key");//获取set里元素个数
//        strings = jedis.sinter("key", "key1");//获取key和key1下对应元素的交集
//        strings = jedis.sunion("key", "key1");//获取key和key1下对应元素的并集
//        strings = jedis.sdiff("key", "key1");//获取key和key1下对应元素的差集
//
//        //(6).hash操作
////        jedis.hmset("key",map);//添加hashMap
////        jedis.hset("key","a","2");//修改hashMap中key=a的元素
////        Map<String,String> map2=jedis.hgetAll("key");//获取hashMap下所有key-value元素
////        Set<String> keys =jedis.hkeys("key");//获取hashMap下的所有key
////        List<String> hvals =jedis.hvals("key");//获取hashMap下的所有value
////        jedis.hexists("key","a");//判断hashMap中是否存在key=a
////        jedis.hlen("key");//获取key下的元素个数
////
////
////        //(7).有序集合操作
////        Map<String,Double> map=new HashMap<>();//key=member,value=score
////        map.put("1",1.51);
////        map.put("2",8.51);
////        map.put("3",3.51);
////        map.put("4",4.51);
////        map.put("5",2.71);
////        jedis.zadd("key",map);//添加zset
////        jedis.zadd("key",1.18,"6");//插入zset
////        //Set<Tuple>strings= jedis.zrangeWithScores("key",0,2);//获取区间内score-member
////        long n=jedis.zcard("key");//获取元素个数
////        double score=jedis.zscore("key","1");//获取map下member=1的score
////        n=jedis.zrank("key","6");//获取map下member=6在所有score中的排名
////        jedis.zrem("key","1");//移除map下member=1的元素
////
////        //(8).排序操作
////        jedis.lpush("key","5","3","10","1","2");
////        List<String> list= jedis.sort("key",new SortingParams().desc());
////        for (int i=0;i<list.size();i++){
////            System.out.println(list.get(i));
////        }
//        redisClose(jedis);
//    }
}
